﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

namespace Slaks.Graphs.GraphBuilder.Extractor
{
    class Extractor
    {
        [DllImport(@"..\..\..\..\extr_api.dll")]
        public static extern int ExtrCreateDocumentMemory(ref IntPtr DocumentMemory);
        // int ExtrCreateDocumentMemory(void **DocumentMemory)


        [DllImport(@"..\..\..\..\extr_api.dll")]

        public static extern int ExtrActivateHighlights(IntPtr DocumentMemory);

        // int ExtrActivateHighlights(void *DocumentMemory);

        [DllImport(@"..\..\..\..\extr_api.dll")]
        public static extern int ExtrSetNumberPhrases(IntPtr DocumentMemory, double DesiredNumber);


        [DllImport(@"..\..\..\..\extr_api.dll")]

        public static extern int ExtrGetHighlightByIndex(IntPtr DocumentMemory, int PhraseIndex, out IntPtr Highlight);

        //int ExtrGetHighlightByIndex(void *DocumentMemory, int HighlightIndex, void **Highlight);



        [DllImport(@"..\..\..\..\extr_api.dll")]

        public static extern int ExtrCreateStopMemory(ref IntPtr StopMemory);

        // int ExtrCreateStopMemory(void **StopMemory);



        [DllImport(@"..\..\..\..\extr_api.dll")]

        public static extern int ExtrSetInputCode(IntPtr DocumentMemory, int CharCodeID);

        // int ExtrSetInputCode(void *DocumentMemory, int CharCodeID);



        [DllImport(@"..\..\..\..\extr_api.dll")]

        public static extern int ExtrReadDocumentBuffer(IntPtr DocumentMemory, IntPtr StopMemory, IntPtr DocumentBuffer, int BufferLength);

        // int ExtrReadDocumentBuffer(void *DocumentMemory, void *StopMemory, void *DocumentBuffer, int BufferLength);



        [DllImport(@"..\..\..\..\extr_api.dll")]

        public static extern int ExtrSignalDocumentEnd(IntPtr DocumentMemory, IntPtr StopMemory);

        // int ExtrSignalDocumentEnd(void *DocumentMemory, void *StopMemory);



        [DllImport(@"..\..\..\..\extr_api.dll")]

        public static extern int ExtrGetPhraseListSize(IntPtr DocumentMemory, ref int PhraseListSize);

        // int ExtrGetPhraseListSize(void *DocumentMemory, int *PhraseListSize);



        [DllImport(@"..\..\..\..\extr_api.dll")]

        public static extern int ExtrGetPhraseByIndex(IntPtr DocumentMemory, int PhraseIndex, out IntPtr Phrase);

        // int ExtrGetPhraseByIndex(void *DocumentMemory, int PhraseIndex, void **Phrase);



        [DllImport(@"..\..\..\..\extr_api.dll")]

        public static extern int ExtrClearStopMemory(IntPtr StopMemory);

        // int ExtrClearStopMemory(void *StopMemory);



        [DllImport(@"..\..\..\..\extr_api.dll")]

        public static extern int ExtrClearDocumentMemory(IntPtr DocumentMemory);

        // int ExtrClearDocumentMemory(void *DocumentMemory);

        [DllImport(@"..\..\..\..\extr_api.dll")]
        public static extern int ExtrActivateHTMLFilter(IntPtr DocumentMemory, IntPtr StopMemory);

        [DllImport(@"..\..\..\..\extr_api.dll")]
        public static extern void ExtrGetErrorMessage(int ErrorCode, ref string ErrorMessage);

        [DllImport(@"..\..\..\..\extr_api.dll")]
        public static extern  int ExtrAddStopWord(IntPtr StopMemory, int LanguageID, int CharCodeID, IntPtr Phrase);



        public static IEnumerable<string> Execute(string fileName, int amount)
        {
            //Create StopMemory used to hold the Stop Words (words not to be considered by extractor when performing the extraction)

            const int ENGLISH = 1;
            const int CODING = 0;
            string script = "script";
            IntPtr StopMemory;
            int ErrorCode = 0;
            
            
                StopMemory = new IntPtr(0);
                IntPtr stopWord = Marshal.StringToHGlobalAnsi(script);
                ErrorCode = ExtrCreateStopMemory(ref StopMemory);
                ErrorCode = ExtrAddStopWord(StopMemory, ENGLISH, CODING, stopWord);
			if(ErrorCode>0)
			{
				Console.WriteLine("Error creating extractor");
			}
            //Activate the Highlights functionality (returns a sentence with the extracted word)
            //string temp = "";
            //ExtrGetErrorMessage(ErrorCode, ref temp);
            //Create Document Memory
            IntPtr DocumentMemory = new IntPtr(0);
            ErrorCode = ExtrCreateDocumentMemory(ref DocumentMemory);

            ErrorCode = ExtrActivateHTMLFilter(DocumentMemory, StopMemory);

            ErrorCode = ExtrActivateHighlights(DocumentMemory);





            ErrorCode = ExtrSetNumberPhrases(DocumentMemory, amount > 30 ? 30 : amount);
            //Read the document into memory 

            string text2Extract;
            using (var sr = new StreamReader(fileName))
            {
                text2Extract = sr.ReadToEnd();
            }
            IntPtr str = Marshal.StringToHGlobalAnsi(text2Extract);

            ErrorCode = ExtrReadDocumentBuffer(DocumentMemory, StopMemory, str, text2Extract.Length);


            //Indicate to extractor this is all of the document

            ErrorCode = ExtrSignalDocumentEnd(DocumentMemory, StopMemory);

            int PhraseListSize = 0;

            ErrorCode = ExtrGetPhraseListSize(DocumentMemory, ref PhraseListSize);
            IList<string> phraseList = new List<string>(PhraseListSize);
            for (int i = 0; i < PhraseListSize; i++)
            {
                IntPtr Phrase;
                ErrorCode = ExtrGetPhraseByIndex(DocumentMemory, i, out Phrase);
                string currPhrase = Marshal.PtrToStringAnsi(Phrase).ToUpper();
                phraseList.Add(currPhrase.ToLower());
            }
            Marshal.Release(str);
            ErrorCode = ExtrClearDocumentMemory(DocumentMemory);
            ErrorCode = ExtrClearStopMemory(StopMemory);
            return phraseList;

        }
    }
}
